using System;
using System.Windows.Forms;

namespace SnarlGMailNotifier.Classes.Animations
{
    public delegate void AnimationFinishedDelegate(object sender, EventArgs e);

    public abstract class AnimationBase
    {
        protected Form m_formToAnimate = null;
        protected int m_intDuration;
        
        protected delegate void SetSizeDelegate(Form form, int sizeValue);
        protected delegate void SetOpacityDelegate(Form form, double opacityValue);
        protected delegate void SetBooleanDelegate(Form form, bool booleanValue);

        protected DateTime m_datStartTime = DateTime.MinValue;
        protected DateTime m_datStopTime = DateTime.MinValue;

        public delegate void AnimationStepChangedDelegate(object sender, AnimationStepEventArgs e);
        
        public abstract event AnimationFinishedDelegate AnimationFinished;
        public abstract event AnimationStepChangedDelegate AnimationStepChanged;

        protected AnimationBase(int duration)
        {
            this.m_intDuration = duration;
        }

        public int Duration
        {
            get { return this.m_intDuration; }
            set { this.m_intDuration = value; }
        }

        public Form FormToAnimate
        {
            get { return this.m_formToAnimate; }
        }

        protected double CalculateCurrentStepPercent(DateTime startTime, DateTime stopTime, DateTime currentTime)
        {
            return (((double)(currentTime.Ticks - startTime.Ticks)) / (double)(stopTime.Ticks - startTime.Ticks));
        }

        public abstract void StartAnimation(Form form);

        

        protected void SetWidth(Form form, int width)
        {
            if (form.InvokeRequired)
            {
                SetSizeDelegate d = new SetSizeDelegate(SetWidth);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, width
                    });
            }
            else
            {
                form.Width = width;
            }
        }

        protected void SetHeight(Form form, int height)
        {
            if (form.InvokeRequired)
            {
                SetSizeDelegate d = new SetSizeDelegate(SetHeight);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, height
                    });
            }
            else
            {
                form.Height = height;
            }
        }

        protected void SetLeft(Form form, int left)
        {
            if (form.InvokeRequired)
            {
                SetSizeDelegate d = new SetSizeDelegate(SetLeft);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, left
                    });
            }
            else
            {
                form.Left = left;
            }
        }

        protected void SetTop(Form form, int top)
        {
            if (form.InvokeRequired)
            {
                SetSizeDelegate d = new SetSizeDelegate(SetTop);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, top
                    });
            }
            else
            {
                form.Top = top;
            }
        }

        protected void SetOpacity(Form form, double opacity)
        {
            if (form.InvokeRequired)
            {
                SetOpacityDelegate d = new SetOpacityDelegate(SetOpacity);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, opacity
                    });
            }
            else
            {
                form.Opacity = opacity;
            }
        }

        protected void SetVisible(Form form, bool boolean)
        {
            if (form.InvokeRequired)
            {
                SetBooleanDelegate d = new SetBooleanDelegate(SetVisible);
                form.Invoke(
                    d,
                    new object[] 
                    { 
                        form, boolean
                    });
            }
            else
            {
                form.Visible = boolean;
            }
        }
    }


    public class AnimationStepEventArgs : EventArgs
    {
        private double m_dblPercent;

        public AnimationStepEventArgs(double percent)
        {
            this.m_dblPercent = percent;
        }

        public double Percent
        {
            get { return this.m_dblPercent; }
        }
    
    }
}
